package com.platform.core.service.impl;

import com.platform.comm.service.impl.CommonBizImpl;
import com.platform.comm.entity.CommDataInfoEntity;
import com.platform.comm.entity.QCommDataInfoEntity;
import com.platform.comm.exceptions.BizException;
import com.platform.comm.exceptions.RestApiException;
import com.platform.comm.jwt.JwtTokenUtil;
import com.platform.comm.jwt.TokenInfoUtil;
import com.platform.comm.repository.CommDataInfoRepository;
import com.platform.comm.service.ICommDataInfoBiz;
import com.platform.comm.util.StringUtil;
import com.platform.dto.DepartQo;
import com.platform.dto.UserQo;
import com.platform.core.security.auth.AuthenticationFacade;
import com.platform.core.service.SysDepartService;
import com.platform.core.service.SysUserService;
import com.platform.oss.core.StandardOssClient;
import com.platform.vo.ExcelCfgDto;
import com.platform.vo.UploadApiDto;
import lombok.extern.log4j.Log4j2;
import org.apache.commons.lang3.StringUtils;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;
import java.net.URLDecoder;
import java.time.LocalDateTime;
import java.util.Map;
import java.util.Optional;
import java.util.Properties;

/**
 * @author Administrator
 */
@Service
@Log4j2
public class CommDataInfoBizImpl extends CommonBizImpl<CommDataInfoRepository, CommDataInfoEntity, String> implements ICommDataInfoBiz {
    private final SysUserService sysUserService;
    private final SysDepartService sysDepartService;
    private final ResourceLoader resourceLoader;
    private final TokenInfoUtil tokenInfoUtil;

    @javax.annotation.Resource(name="${oss.defaultBeanName}")
    private StandardOssClient standardOssClient;

    public CommDataInfoBizImpl(CommDataInfoRepository commDataInfoRepository, SysUserService sysUserService,
                               SysDepartService sysDepartService, ResourceLoader resourceLoader,
                               TokenInfoUtil tokenInfoUtil) {
        super(commDataInfoRepository);
        this.sysUserService = sysUserService;
        this.sysDepartService = sysDepartService;
        this.resourceLoader = resourceLoader;
        this.tokenInfoUtil = tokenInfoUtil;
    }

    @Override
    public CommDataInfoEntity queryCommDataImpById(String id) {
        Optional.ofNullable(id).orElseThrow(() -> new RuntimeException("ID不能为空!"));
        QCommDataInfoEntity qCommDataImpEntity = QCommDataInfoEntity.commDataImpEntity;
        Optional<CommDataInfoEntity> optional = this.queryOne(qCommDataImpEntity.id.eq(id));
        return optional.orElse(null);
    }

    @Override
    public CommDataInfoEntity updateCommDataImp(CommDataInfoEntity entity) {
        Assert.notNull(entity.getId(), "更新时，id不能为空");
        return repository.save(entity);
    }

    @Override
    public CommDataInfoEntity saveUploadRecord(String resourceKey, MultipartFile uploadFile) {
        return null;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public CommDataInfoEntity saveRecord(Map<String, String> paramsMap, MultipartFile uploadFile) {
        Assert.notNull(uploadFile, "批量导入附件不能为空");
        JwtTokenUtil.JwtUser jwtUser = AuthenticationFacade.getUser();
        CommDataInfoEntity commDataImpEntity = new CommDataInfoEntity();
        commDataImpEntity.setId(StringUtil.getUUID());
        if (jwtUser != null) {
            commDataImpEntity.setUploadUser(jwtUser.getId());
            commDataImpEntity.setUploadDept(jwtUser.getDepartId());
        }
        try {
            commDataImpEntity.setFileName(URLDecoder.decode(Optional.ofNullable(uploadFile.getOriginalFilename()).orElse(""), "UTF-8"));
            commDataImpEntity.setFileUrl(standardOssClient.upload(uploadFile.getInputStream(),commDataImpEntity.getFileName()));
        } catch (Exception e) {
            log.error("批量导入附件异常",e);
            throw new RestApiException("批量导入附件异常");
        }
        commDataImpEntity.setFileLength(new BigDecimal(uploadFile.getSize()));
        commDataImpEntity.setUploadDate(LocalDateTime.now());
        this.saveEntity(commDataImpEntity);
        return commDataImpEntity;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public CommDataInfoEntity saveRecord(String originalFileName, BigDecimal size, InputStream inputStream) {
        Assert.notNull(inputStream, "批量导入附件不能为空");
        CommDataInfoEntity commDataImpEntity = new CommDataInfoEntity();
        commDataImpEntity.setId(StringUtil.getUUID());
        commDataImpEntity.setUploadUser(AuthenticationFacade.getUserId());
        commDataImpEntity.setUploadDept(AuthenticationFacade.getDepartId());
        try {
            commDataImpEntity.setFileName(URLDecoder.decode(Optional.ofNullable(originalFileName).orElse(""), "UTF-8"));
            commDataImpEntity.setFileUrl(standardOssClient.upload(inputStream,commDataImpEntity.getFileName()));
        } catch (Exception e) {
            throw new RestApiException("批量导入附件异常");
        }
        commDataImpEntity.setFileLength(size);
        commDataImpEntity.setUploadDate(LocalDateTime.now());
        this.saveEntity(commDataImpEntity);
        return commDataImpEntity;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public CommDataInfoEntity saveUploadRecord(UploadApiDto uploadFile) {
        Assert.notNull(uploadFile, "批量导入附件不能为空");
        JwtTokenUtil.JwtUser jwtUser = tokenInfoUtil.getUser();
        CommDataInfoEntity dirUploadRecordEntity = new CommDataInfoEntity();
        dirUploadRecordEntity.setId(StringUtil.getUUID());
        dirUploadRecordEntity.setUploadUser(jwtUser.getId());
        dirUploadRecordEntity.setUploadDept(jwtUser.getDepartId());
        dirUploadRecordEntity.setFileName(uploadFile.getOriginalFilename());
        dirUploadRecordEntity.setFileLength(new BigDecimal(uploadFile.getSize()));
        dirUploadRecordEntity.setFileUrl(uploadFile.getFileUrl());
        dirUploadRecordEntity.setUploadDate(LocalDateTime.now());
        this.saveEntity(dirUploadRecordEntity);
        return dirUploadRecordEntity;
    }

    @Override
    public CommDataInfoEntity initCommDataInfo(String importId) {
        CommDataInfoEntity commDataInfoEntity = queryCommDataImpById(importId);
        Assert.notNull(commDataInfoEntity, "无效的批量导入上传信息");


        DepartQo departQo = this.sysDepartService.queryDepartById(commDataInfoEntity.getUploadDept());
        if (departQo != null) {
            commDataInfoEntity.setUploadOrgName(departQo.getDepartName());
        }
        UserQo userQo = sysUserService.getByUserId(commDataInfoEntity.getUploadUser());
        if (userQo != null) {
            commDataInfoEntity.setUploadUserName(userQo.getRealName());
        }
        return commDataInfoEntity;
    }

    @Override
    public ExcelCfgDto initImpConfig(String moduleName, String configType) {
        String module = StringUtils.substringBefore(moduleName, "Controller");
        Resource resource = resourceLoader.getResource("classpath:batch.config/SysImpCfg.properties");
        Properties prop = new Properties();

        try {
            prop.load(resource.getInputStream());
        } catch (IOException e) {
            log.error(e.getMessage(), e);
            throw BizException.of("未找到系统管理模块导入对应配置文件");
        }

        return initExcelCfgDto(module, prop, configType);
    }

    @Override
    public void delete(String attachmentId) {
        deleteAndFlush(fetchById(attachmentId));
    }

    @Override
    public InputStream downLoadFile(String attachmentId) {
        return standardOssClient.download(fetchById(attachmentId).getFileUrl());
    }

    private ExcelCfgDto initExcelCfgDto(String moduleName, Properties prop, String configType) {
        ExcelCfgDto impExcelCfg = ExcelCfgDto.of();

        if (configType.equals(IMPORT)) {
            impExcelCfg.setFirstRowNum(Integer.valueOf(prop.getProperty(moduleName + ".startRow", "1")));
            impExcelCfg.setFirstColNum(Integer.valueOf(prop.getProperty(moduleName + ".startCol", "1")));
            impExcelCfg.initFields(prop.getProperty(moduleName + ".fieldNames").split(","));
        } else {
            impExcelCfg.initFields(prop.getProperty(moduleName + ".fieldNames.out").split(","));
            impExcelCfg.setSheetName(prop.getProperty(moduleName + ".tableName"));
            impExcelCfg.setTableName(prop.getProperty(moduleName + ".tableName"));
        }

        for (int i = 0; i < impExcelCfg.getColumns().size(); i++) {
            impExcelCfg.getColumns().get(i)
                    .setTitle(prop.getProperty(moduleName + "." + impExcelCfg.getColumns().get(i).getFieldName()));
        }

        return impExcelCfg;
    }



}
